﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Threading;
using UnityEngine.SceneManagement;
using System.Text;

public class GameController : MonoBehaviour {

	private GameController(){ 
		_instance = this;
	}
	private static GameController _instance = null;
	public static GameController GetInstance(){
		if (_instance == null) {
			return null;
		}
		return _instance;
	}
		
	private int[,] map = new int[HEIGHT, WIDTH];

	public const int WIDTH = 28;
	public const int HEIGHT = 28;

	public Config config;

	/**
	 * 游戏状态：
	 * 0 - 不在游戏
	 * 1 - 正常游戏中
	 * 2 - 敌方暂停
	 */ 
	public int Status; 

	private string mapText;
	private int mapOk;
	private void InitChapter(){       // 根据 _chapter 初始化 chapter  

		for (int i = 0; i < HEIGHT; i++) {
			map [i, 0] = -1;
			map [i, WIDTH - 1] = -1;
		}
		for (int i = 0; i < WIDTH; i++) {
			map [0, i] = -1;
			map [HEIGHT - 1, i] = -1;
		}	
        
		mapOk = 0;
		StartCoroutine ("ReadMap");
	}

	IEnumerator ReadMap()
	{
		var p = "file:///" + Application.streamingAssetsPath + "/MapConfig/" + config.Chapter + ".txt";
		var w = new WWW (p);
		yield return w;
		mapText = w.text;
		mapOk = 1;
	}

	/**
	 * 基地防御
	 * 是所有基地围墙共同的 parent，以便基地防御变化时找到基地围墙
	 */
	private GameObject baseDefense;
	private void GenChapter() {   // 生成关卡

		baseDefense = GameObject.Find ("BaseDefense");

		// 生成地图固定位置元素（墙、河、。。。）
		GameObject obj; 
		for (int i = 0; i < HEIGHT; i++) {
			for (int j = 0; j < WIDTH; j++) {
				if (1 <= i && i <= 3 && 11 <= j && j <= 15) {
					map [i, j] = 1;
					continue;
				}
				switch (map [i, j]) {
				case -1:  // 边界
					obj = Create ("border", new Vector3(j, 0, i));
					break;
				case 0:   // 空地
					//obj = Create ("empty", new Vector3(j, 0, i));
					break;
				case 1:   // 木墙
					obj = Create ("wall_wood", new Vector3(j, 0, i));
					break;
				case 2:   // 铁墙
					obj = Create ("wall_iron", new Vector3(j, 0, i));
					break;
				case 3:   // 河
					obj = Create ("river", new Vector3(j, 0, i));
					break;
				case 4:   // 草地
					obj = Create ("grass", new Vector3(j, 0, i));
					break;
				case 5:   // 滑地
					obj = Create ("slide", new Vector3 (j, 0, i));
					break;
				default:
					Debug.Log ("地图存在不能识别为具体物体的标识!");
					break;
				}
			}
		}
			

		// 生成玩家
		GenPlayer1 (config.Player1);
		GenPlayer2 (config.Player2);
	}

	void Awake(){
		_enemyType = new int[26];  // 每关固定26 个敌人，该数组用于存放26 个敌人的类型
		_enemyList = new List<GameObject>();

		config = GameObject.Find("/ConfigCube").GetComponent<Config> ();

		InitChapter ();
	}

	private List<GameObject> foodList =	 new List<GameObject>();
	public void GenFood(){
		Point pos = RandomSelectLocation (2);               						      // 随机食物所在位置

		int type = Random.Range (0, Food.FOOD_TYPE_NUM);        						  // 随机一种食物
		GameObject food = Create ("food" + "_" + type, new Vector3(pos.Y, 20, pos.X));    // 创建它
		food.transform.position = new Vector3(pos.Y+1, 20, pos.X+1);

		Food foodComponent = food.GetComponent<Food> ();  		 						  // 获取 food 组件
		foodComponent.Type = (Food.FoodType)type;                						  // 设置食物类型
		foodComponent.Pos = pos;                                 						  // 随机选择它在地图中的位置

		foodList.Add (food);
	}

	public Point RandomSelectLocation(int size){                 // 随机选择一个位置
		Point res = new Point();
		res.X = Random.Range(1, WIDTH-1-size);
		res.Y = Random.Range(1, HEIGHT-1-size);
		return res;
	}
		
	private List<GameObject> _enemyList; 

	public void BombBurst(GameObject player, GameObject food){  // 坦克吃到炸弹
		int index = 0;
		while(_enemyList.Count > index){
			if (_enemyList [index].GetComponent<Tank> ().CanKill == false) {
				index++;
				continue;
			}
			Clear(_enemyList [index]);
		}
		Destroy (food);
	}


	public void HaltEnemy(GameObject player, GameObject food){
		Status = 3;
		HaltTimer = Config.foodConfig.EffectivenessDuration[(int)Food.FoodType.HALT];  
		Destroy (food);
	}

	/**
	 * 基地防御形态变化
	 */
	private void BaseDefenseChange(){

		if (baseDefense.tag.Equals ("w")) {
			baseDefense.tag = "i";
		} else {
			baseDefense.tag = "w";
		}

		for (int i = 0; i < baseDefense.transform.childCount; i++) {
			baseDefense.transform.GetChild (i).gameObject.SetActive (false);
		}

		for (int i = 1; i < 9; i++) {
			Utils.SetActive ( baseDefense.transform.Find (baseDefense.tag + i).gameObject, true );
		}

	}
		

	public void UpgradeBaseDefense(GameObject player, GameObject food){  // 坦克吃到铁墙
		if(IronWallTimer==0){
			BaseDefenseChange ();
		}
		IronWallTimer = Config.foodConfig.EffectivenessDuration[(int)Food.FoodType.IRON];
		Destroy (food);
	}

	public void PlusLife(GameObject player, GameObject food){  			// 坦克吃到加生命
		if (player == _player1) {
			config.Player1Num++;
		} else {
			config.Player2Num++; 
		}
		Destroy (food);
	}

	public void ChangeInvincible(GameObject player, GameObject food){   // 坦克吃到无敌
		player.GetComponent<Tank>().CanKill = false;
		Destroy (food);
	}

	private GameObject _player1;
	private GameObject _player2;

	public void Upgrade(GameObject player, GameObject food){  // 坦克升级
		Tank tank = player.GetComponent<Tank>();
		if (tank.Type == 6 || tank.Type == 9) {  // 已经满级
			foodList.Remove(food);
			Destroy (food);
			return;
		}
		GameObject newObj = Create ("tank_"+(tank.Type+1), player.transform.position);
		newObj.transform.rotation = player.transform.rotation;

		Tank newTank = newObj.GetComponent<Tank> ();
		newTank.Copy (tank);
		newTank.Type = tank.Type + 1;

		if (player == _player1) {
			_player1 = newObj;
			config.Player1 = newTank.Type;
		} else {
			_player2 = newObj;
			config.Player2 = newTank.Type;
		}
		tank.Clear ();
		Destroy (player);
		foodList.Remove (food);
		Destroy (food);
	}
		
	public void Degrade(GameObject player){  // 坦克降级
		Tank tank = player.GetComponent<Tank> ();
		if (tank.Type == 4 || tank.Type == 7) {  // 已经是最低级
			if (_player1 == player) {  // 玩家一
				Clear (player);
			} else {
				Clear (player);
			}
		} else {
			GameObject newObj = Create ("tank_" + (tank.Type - 1), player.transform.position);
			newObj.transform.rotation = player.transform.rotation;

			Tank newTank = newObj.GetComponent<Tank> ();
			newTank.Copy (tank);
			newTank.Type = tank.Type - 1;

			if (player == _player1) {
				_player1 = newObj;
				config.Player1 = newTank.Type;
			} else {
				_player2 = newObj;
				config.Player2 = newTank.Type;
			}
			Destroy (player);
		}
	}

	//private int[] _enemyNum = new int[4];  // 四种类型敌人剩余数量

	private Point RandomSelectEnemyPos(){
		int r = Random.Range (0, 3);
		Point res = new Point ();
		if (r == 0) {
			res.FX = 25.445f;
			res.FY = 1.555f;
		} else if (r == 1) {
			res.FX = 25.445f;
			res.FY = 13.445f;
		} else {
			res.FX = 25.445f;
			res.FY = 25.445f;
		}
		return res;
	}

	private int[] _enemyType;    // 敌人类型
	private int _index = 0;      // 下一个生成的敌人
	private void GenEnemy(){     // 生成敌人
		if (_index >= 26) {      // 敌人全灭
			return; 
		}
        
		Point pos = RandomSelectEnemyPos ();
		GameObject obj = Create ("tank_" + (_enemyType[_index]&3), new Vector3 (pos.FY, 5, pos.FX));

		Tank tank = obj.GetComponent<Tank> ();
		tank.Type = (_enemyType[_index]&3);
		tank.WithFood = (_enemyType [_index] & 4) > 0;
		tank.CanKill = false;

		_index++;
		_enemyList.Add (obj);
	}

	private void GenPlayer1(int type=4){
		if (config.Player1Num <= 0) {
			config.Player1Num = -1;
			return;
		}
		config.Player1Num--;
		_player1 = Create ("tank_" + type, new Vector3 (9.445f, 5, 1));
		Tank tank = _player1.GetComponent<Tank> ();
		tank.Type = type;
		tank.CanKill = false;
	}

	private void GenPlayer2(int type=7){
		if (config.Player2Num <= 0) {
			config.Player2Num = -1;
			return;
		}
		config.Player2Num--;
		_player2 = Create ("tank_"+type, new Vector3 (17.445f, 5, 1));
		Tank tank = _player2.GetComponent<Tank> ();
		tank.Type = type;
		tank.CanKill = false;
	}

	public GameObject Create(string name, Vector3 position){
		GameObject res = Instantiate (Resources.Load<GameObject> (@"prefabs\" + name));
		res.transform.position = position;

		return res;
	}

	public void Clear(GameObject obj) {  // 可移动物体的回收
		string tag = obj.tag;
		//print ("清除tag 为" + tag + "的物体");
		if (tag.Equals ("tank")) {  // 回收坦克，有爆炸效果
			if (_player1 == obj) {   // 如果是玩家一
				GenPlayer1 ();
			} else if (_player2 == obj) {  // 如果是玩家二
				GenPlayer2 ();
			} else {  // 敌方坦克
				_enemyList.Remove (obj);
			}
			Instantiate (Resources.Load<GameObject> ("prefabs/bomb01"), obj.transform.position, obj.transform.rotation);
			obj.GetComponent<Tank> ().Clear ();
			Destroy (obj);
		} else if (tag.Equals ("wall")) {
			//print ("回收编号为" + obj.name + "的墙");
			if (obj.transform.parent == null) {  
				Destroy (obj);
			} else {
				//print ("这不是父节点" + obj.name);
				GameObject fa = obj.transform.parent.gameObject;
				Wall wall = fa.GetComponent<Wall> ();
				//print ("obj.name= [" + (System.Convert.ToInt32 (obj.name) - 1) + "],wall.count = " + wall.GetChildCount ());
				wall.Exists [System.Convert.ToInt32 (obj.name) - 1] = false;

				if (wall.GetChildCount () == 0) {
					//print ("准备回收父墙");
					Clear (fa);
				} else {
					//print ("准备回收自己");
					Destroy (obj);
				}
			}
		} else if (tag.Equals ("fa")) {
			Destroy (obj);
		} else if (tag.Equals ("food")) {
			foodList.Remove (obj);
			Destroy (obj);
		} else if (tag.Equals ("ring")) {
			Destroy (obj);
		} else if (tag.Equals ("base_defense")) {  // 对于基地防御的回收，特别处理

			obj.SetActive (false);
			if (obj.transform.parent.gameObject.name.Equals ("BaseDefense")) {  // 如果obj 是基地防御中的铁墙，那么不做其他处理
			
			} else {  // 如果obj 是基地防御中的木墙，那么要判断是否有父节点，如果有父节点并且所有兄弟节点 active 都被设置成false，那么父节点也需设置成 false
				Wall wall = obj.transform.parent.GetComponent<Wall> ();
				wall.Exists [System.Convert.ToInt32 (obj.name) - 1] = false;
				if (wall.GetChildCount () == 0) {  // 将父节点的 active 设置成 false
					obj.transform.parent.gameObject.SetActive(false);
				}

			}

		}
	}

	public void AddScore(int player, GameObject obj) {
		if (obj.tag.Equals ("tank")) {
			config.ScorePoint [obj.GetComponent<Tank> ().Type, player]++;
		}
	}

	public void HouseBeAttacked() {
		config.Status = 0;
		GameOver ();
	}

	void GameOver() {
		SceneManager.LoadScene ("Settlement");
	}

	void Start(){
		Status = 1;
		HaltTimer = 0;
		GenEnemyTimer = 0;
		IronWallTimer = 0;
	}
		

	void OnGUI(){
		
		GUI.skin.label.fontSize = 20;

		if (Time.timeScale == 0) {
			GUI.color = Color.red;
			GUI.Label ( new Rect(Screen.width/2-35, Screen.height/2-20, 150, 40), "游戏暂停···" );
			GUI.color = Color.white;
		}
			

		int enemyNum = 26 - _index;

		StringBuilder sb = new StringBuilder ();
		for (int i = 0; i < enemyNum; i++) {
			if (i % 2 == 0)
				sb.Append ("\n");
			sb.Append ("X");
		}

		GUI.Label (new Rect (Screen.width - 100, 20, 200, 300), sb.ToString());

		GUI.Label (new Rect (Screen.width - 100, 350, 200, 50), "P1:\n" + config.Player1Num);
		GUI.Label (new Rect (Screen.width - 100, 425, 200, 50), "P2:\n" + config.Player2Num);
		GUI.Label (new Rect (Screen.width - 100, 500, 200, 50), "第 " + config.Chapter + " 关");
	}

    private Config _config;

	List<GameObject> tempList = new List<GameObject>();
	public float GenEnemyTimer;    // 生成敌人的间隔
	public float HaltTimer;        // 暂停食物 效果时长
	public float IronWallTimer;    // 基地铁墙 效果时长

	public AudioClip loopMusic;
	public AudioSource audioSource;

	void Update(){

		if (Status > 0) {

			if (mapOk == 2) {      // 地图加载设置完成

				if (Time.timeScale == 0) {
					
				} else {
					if (audioSource.isPlaying == false) {
						audioSource.clip = loopMusic;
						audioSource.loop = true;
						audioSource.Play ();
					}
				}

				if (IronWallTimer > 0) {
					IronWallTimer-=Time.deltaTime;
					if (IronWallTimer <= 0) {
						BaseDefenseChange ();
					}
				}

				if (HaltTimer > 0) {
					HaltTimer-=Time.deltaTime;
					if (HaltTimer <= 0) {
						Status = 1;
					}
				}

				GenEnemyTimer-=Time.deltaTime;
				if (GenEnemyTimer <= 0) {
					GenEnemyTimer = Config.gameConfig.GenEnemyTimer;
					GenEnemy ();
				}

				if (Input.anyKeyDown) {
					if (Input.GetKey (KeyCode.Escape)) {
						Time.timeScale = 1 - Time.timeScale;

						if (Time.timeScale == 0) {
							audioSource.Pause ();
						} else {
							audioSource.Play ();
						}

					}
				}

				if (config.Player1Num < 0 && config.Player2Num < 0) {
					config.Status = 0;
					GameOver ();
				}

				if (_index == 26 && _enemyList.Count == 0) {
					config.Status = 1;
					GameOver ();
				}



			}

			if (mapOk == 0)    // 地图还在加载
				return;

			if (mapOk == 1) {  // 地图刚加载好
				string text = mapText;
				int j = 0, k = 0;
				for (int i = 0; i < text.Length && j < 676; i++) {
					if ('0' <= text [i] && text [i] <= '9') {
						map[ 26-j/26, j%26+1 ] = text[i]-'0';
						j++;
					}
					k++;
				}
				j = 0;
				for (int i = k+2; j < 26; i++) {
					_enemyType [j] = (text[i]-'0') | (text[i+28]=='0'?0:4);
					j++;
				}

				GenChapter ();
				mapOk = 2;
			}
		}
	}
}
